#include <openssl/bio.h>
#include <openssl/evp.h>
#include <string>
#include <vector>

#ifndef BASE64UTILS_H
#define BASE64UTILS_H

// based on  OpenSSL 3.0
class Base64Utils
{
	public:
	 static std::string base64_encode(const std::string &input)
{
	// 创建 BIO 链：内存源 -> Base64 过滤 -> 内存输出
	BIO *b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 禁用换行符
	BIO *mem = BIO_new(BIO_s_mem());
	BIO_push(b64, mem);

	// 写入数据并刷新
	BIO_write(b64, input.data(), static_cast<int>(input.size()));
	BIO_flush(b64);

	// 获取结果
	char *output_ptr;
	long output_len = BIO_get_mem_data(mem, &output_ptr);
	std::string output(output_ptr, output_len);

	// 清理资源
	BIO_free_all(b64);
	return output;
}

static std::string base64_decode(const std::string &input)
{
	// 创建 BIO 链：内存源 -> Base64 解码 -> 内存输出
	BIO *b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 禁用换行符
	BIO *mem = BIO_new_mem_buf(input.data(), static_cast<int>(input.size()));
	BIO_push(b64, mem);

	// 准备输出缓冲区
	std::vector<char> buffer(input.size());
	int decoded_len = BIO_read(b64, buffer.data(), static_cast<int>(buffer.size()));

	// 验证解码结果
	if (decoded_len < 0) {
		BIO_free_all(b64);
		throw std::runtime_error("Base64 decoding failed");
	}

	// 清理资源并返回结果
	BIO_free_all(b64);
	return std::string(buffer.data(), decoded_len);
}
};

#endif